package cn.com.coding.system.service.impl;

import cn.com.coding.common.utils.PageUtil;
import cn.com.coding.common.utils.Query;
import cn.com.coding.common.utils.RedisUtil;
import cn.com.coding.system.dao.SysUserDao;
import cn.com.coding.system.domin.SysMenuEntity;
import cn.com.coding.system.domin.SysRoleEntity;
import cn.com.coding.system.domin.SysUserEntity;
import cn.com.coding.system.domin.UserInfoEntity;
import cn.com.coding.system.service.SysMenuService;
import cn.com.coding.system.service.SysRoleService;
import cn.com.coding.system.service.SysUserService;
import cn.com.coding.system.service.UserInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    SysRoleService sysRoleService;

    @Autowired
    SysMenuService sysMenuService;

    @Autowired
    UserInfoService userInfoService;

    @Override
    public PageUtil queryPage(Map<String, Object> params) {
        IPage<SysUserEntity> page = this.page(new Query<SysUserEntity>().getPage(params), new QueryWrapper<SysUserEntity>().like("username", params.get("name") != null ? params.get("name") : "").or().like("email", params.get("name") != null ? params.get("name") : ""));

        return new PageUtil(page);
    }

    @Override
    public SysUserEntity getByUserName(String username) {
        return getOne(new QueryWrapper<SysUserEntity>().eq("username", username));
    }

    @Override
    public String getUserAuthorityInfo(String userPid) {

        SysUserEntity sysUser = this.baseMapper.selectById(userPid);

        UserInfoEntity userInfoEntity = userInfoService.getOne(new QueryWrapper<UserInfoEntity>().eq("pid", userPid));

        String userName = sysUser == null ? userInfoEntity.getPhone() : sysUser.getUsername();

        //  ROLE_admin,ROLE_normal,sys:user:list,....
        String authority = "";

        if (redisUtil.hasKey("GrantedAuthority:" + userName)) {
            authority = (String) redisUtil.get("GrantedAuthority:" + userName);

        } else {
            // 获取角色编码
            List<SysRoleEntity> roles = sysRoleService.list(new QueryWrapper<SysRoleEntity>().inSql("pid", "select role_pid from sys_user_role where user_pid = " + "'" + userPid + "'"));

            if (roles.size() > 0) {
                String roleCodes = roles.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");
            }

            // 获取菜单操作编码
            List<String> menuPids = this.baseMapper.getNavMenuPids(userPid);
            if (menuPids.size() > 0) {

                List<SysMenuEntity> menus = new ArrayList<>(sysMenuService.listByIds(menuPids));
                // 获取授权
                String menuPerms = menus.stream().map(SysMenuEntity::getPerms).collect(Collectors.joining(","));

                authority = authority.concat(menuPerms);
            }

            redisUtil.set("GrantedAuthority:" + userName, authority, 60 * 60);
        }

        return authority;
    }

    /**
     * TODO 待测试
     *
     * @param username
     */
    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del("GrantedAuthority", username);
    }

    @Override
    public void clearUserAuthorityInfoByRolePid(String rolePid) {
        List<SysUserEntity> userEntities = this.list(new QueryWrapper<SysUserEntity>().inSql("pid", "select user_pid from sys_user_role where role_pid = " + "'" + rolePid + "'"));

        userEntities.forEach(e -> {
            this.clearUserAuthorityInfo(e.getUsername());
        });
    }

    @Override
    public void clearUserAuthorityInfoByMenuPid(String menuPid) {
        List<SysUserEntity> sysUserEntity = this.baseMapper.listByMenuPid(menuPid);
        sysUserEntity.forEach(e -> {
            this.clearUserAuthorityInfo(e.getUsername());
        });

    }

    @Override
    public SysUserEntity selectByUserNameAndPassWord(String username, String password) {
        return this.baseMapper.selectByUserNameAndPassWord(username, password);
    }

    @Override
    public List<String> getNavMenuPids(String userPid) {
        return this.baseMapper.getNavMenuPids(userPid);
    }


}